package com.ants.boot.config;

import com.ants.boot.core.Response;
import com.ants.boot.core.exception.NewNoHandleFoundException;
import com.ants.boot.core.exception.NotSupportFormatException;
import com.ants.boot.core.exception.UploadFileException;
import com.ants.boot.core.security.exception.CustomException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.*;

/**
 * @author 蚂蚁会花呗
 * @date 2022/1/11 15:03
 * 全局异常
 */
@RestControllerAdvice
public class RestExceptionHandle {

    Logger logger = LoggerFactory.getLogger(RestExceptionHandle.class);

    /**
     *
     * @param e
     * @return
     */
    @ExceptionHandler(value =Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    public Response exceptionHandler(Exception e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.INTERNAL_SERVER_ERROR.value(),"服务器异常，请稍后重试！", StringUtils.EMPTY);
    }


    /**
     * 因为该全局异常 会比 AccessDeniedHandler
     * 先捕获 AccessDeniedException 异常，因此配置了全局异常之后会导致自定义实现的AccessDeniedHandler失效，
     * 这里可以捕获异常之后做处理，直接返回无权限的情况，也可再抛出，由自定义的AccessDeniedHandler实现类处理
     * @param e
     * @return
     */
    @ExceptionHandler(value = AccessDeniedException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public Response accessDeniedException(AccessDeniedException e){
        logger.error(e.toString(),e);
        return new Response(HttpStatus.UNAUTHORIZED.value(),"该用户无权限访问，请联系管理员！", StringUtils.EMPTY);
    }
    /**
     * 传参数序列化时的错误
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpMessageNotReadableException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public Response httpMessageNotReadableException(HttpMessageNotReadableException e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.BAD_REQUEST.value(),"请求参数异常！", StringUtils.EMPTY);
    }

    /**
     * 方法参数校验
     * @param e
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    private Response methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException  e) {
        logger.error(e.toString(), e);
        return new Response(HttpStatus.BAD_REQUEST.value(),e.getBindingResult().getFieldError().getDefaultMessage(), StringUtils.EMPTY);
    }


    /**
     * SecurityUtils 获取用户异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = CustomException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    private Response customException(CustomException e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.UNAUTHORIZED.value(),e.getMessage(), StringUtils.EMPTY);
    }

    /**
     * 不支持的格式上传异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = NotSupportFormatException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.UNSUPPORTED_MEDIA_TYPE)
    private Response notSupportFormatException(NotSupportFormatException e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.UNSUPPORTED_MEDIA_TYPE.value(),e.getMessage(), StringUtils.EMPTY);
    }


    /**
     * 不支持的格式上传异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = UploadFileException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
    private Response uploadFileException(UploadFileException e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.INTERNAL_SERVER_ERROR.value(),e.getMessage(), StringUtils.EMPTY);
    }

    /**
     * 不被允许的请求方式
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.METHOD_NOT_ALLOWED)
    private Response httpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.METHOD_NOT_ALLOWED.value(),e.getMessage(), StringUtils.EMPTY);
    }


    /**
     * 请求路由找不到
     * @param e
     * @return
     */
    @ExceptionHandler(value = NewNoHandleFoundException.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.NOT_FOUND)
    private Response httpRequestMethodNotSupportedException(NewNoHandleFoundException e){
        logger.error(e.toString(), e);
        return new Response(HttpStatus.NOT_FOUND.value(),e.getMessage(), StringUtils.EMPTY);
    }


}
